The Macintosh toolbox does not provide any way to get the icon of a file or folder, as displayed by the Finder. One can use AppleScript to get an icon family, but the AppleScript Finder Guide doesn’t seem to give enough information to do this from a language other than AppleScript. In any case, using AppleEvents to get icons from the Finder would probably be too slow for some applications.
Icons can come from various sources. The picture at the beginning of this document shows several cases:
• an icon retrieved from the desktop database, using the file’s type and creator codes
• a generic icon from the System, determined from the file type
• a generic icon from the Finder, determined from the file type
• an icon for a special folder (one of those found by FindFolder)
• a folder icon that indicates that the folder is shared or mounted
• a custom icon for a folder, coming from resources in an invisible file
• a volume icon, retrieved from the disk driver
Find_icon finds all these kind of icons, and attempts to find the same icon that would be displayed by the Finder. If the file or folder has a label color, that label color will be applied to the suite. Mini icons (12x16) are not supported.
The Find_icon API
Typically, you will only call the main entry point, which has this prototype:
pascal OSErr Find_icon(
/* --> */ const FSSpec *thing,
/* --> */ MetaSelectorValue icon_selector,
/* <-- */ Handle *the_suite
);
For the icon selector value, you can use the icon selector masks defined in <Icons.h>, or you can use one of the special values kSelectorSmallThenLarge or kSelectorLargeThenSmall. To see why you might want to use these special values, let’s suppose you intend to display only small icons. Then you might think of using kSelectorAllSmallData, so as not to waste time and memory fetching large icons that would not be used. But what if some particular file has only large icons? A scaled-down large icon is better than no icon at all. Hence, you could use kSelectorSmallThenLarge, to say that you prefer small icons, but if none are found, try again for large icons.
So long as no error occurs, Find_icon returns an icon suite handle, which you can then pass to Icon Utilities routines such as PlotIconSuite. It is your responsibility to dispose of the suite, including its icons, when you are done with it.
All functions (except for a few small static functions) are documented in their header files.
Source vs. Libraries vs. Code Resources
Find_icon is provided in source code, libraries, and code resources. If you use the 68K library, you may need to rebuild it with the settings appropriate for your project (large vs. small code model, 4-byte vs. 2-byte ints, A4 vs. A5 globals, and all that).
To use the Find_icon library or source, you also need to use the MoreFiles library by Jim Luther and Nitin Ganatra. The MoreFiles function DTGetIcon is used to get icons from the desktop database or Desktop file. This version of Find_icon was developed with MoreFiles 1.4.5.
Unless you plan to tweak the code or call Find_icon functions other than the main entry point, you would probably find it easier to use a code resource rather than a library or the source code. I made a safe-fat code resource for the heck of it, but to be honest, it would probably be just as well to use the straight 68K code resource. The File Manager isn’t native yet, and even if it were, finding icon suites would probably be i/o bound.
Safe-fat Code Resources
Quoting MixedMode.r, “A safe fat resource starts with 68K code which is executed the first time the resource is called. This code determines if MixedMode is present. If so, a routine descriptor is moved to the beginning of the resource. If not, a branch instruction to the 68K portion of the code is placed at the beginning of the resource. Therefore, the first time the resource is executed, there is some overhead incurred. However, subsequent calls will be fast.” In my experience, if the code resource is being used on a PowerPC machine, then the PowerPC code will be executed, even if the resource is called by 68K code.
The demo app illustrates how to load and call the safe-fat code resource. The demo indexes through the files and folders within its home directory, showing the icon family of each item.
If you want to modify or rebuild the code resource, here is the procedure:
(1) Build the project FindIconCR68K.µ, which creates a resource file Find_icon68K.rsrc.
(2) Build the project FindIconCRPPC.µ, which creates a resource file Find_iconPPC.rsrc.
(3) Build the project MakeFat.µ, which creates a resource file FatRes.rsrc.
(4) Open FatRes.rsrc with ResEdit or Resorcerer, and copy out the PROC resource. This is the safe-fat code resource, which I have placed in the file Find_icon_fat.rsrc.
Usage and Distribution Rules
You may incorporate this sample code into your applications without restriction or fees, though the sample code has been provided “AS IS” and the responsibility for its operation is 100% yours. If you’re going to re-distribute the source, please make it clear that the code was descended from James W. Walker’s code, but that you’ve made changes.
This package may be uploaded to Internet or online service libraries, or placed on CD-ROM collections.